<?php

App::uses('AppController', 'Controller');

class TabletController extends AppController {
    /**
     *        CONTROLLER DATA MEMBERS
     */

    /**
     * Modelos que utiliza
     *
     * Los modelos que usa el controller. Por defecto
     * cake usa el singular basado en el nombre del modelo,
     * pero por asuntos del idioma siempre se ingresa el modelo
     * para evitar posibles problemas.
     *
     * @var array(string)
     */
    public $uses = array('Conductor', 'Recorrido', 'RecorridoRealizado', 'Evento', 'Usuario', 'RecorridoRealizadoEvento', 'Parada', 'RutaParada', 'RecorridoRealizadoParada', 'RecorridoRealizadoUsuarioParada', 'Reserva', 'Bus', 'RecorridoRealizadoHistorico');

    /**
     *        CONTROLLER CALLBACKS METHODS
     */

    public function beforeFilter() {
        parent::beforeFilter();
        //$this->Auth->allow();
        //$this->Auth->allow('login');
        $this->Auth->allow('login', 'buses_get');
        $this->autoRender = false;
    }

    /**
     *        CONTROLLER METHODS (ACTIONS)
     */

    /**
     * Funcion que llama el login despues de recibir los datos de la tableta
     * @return 1 ó 0
     */
    public function login() {
        if ($this->request->is('post')) {
            return $this->Conductor->login(array(
                        "usuario" => $this->request->data["usuario"],
                        "clave" => $this->request->data["clave"],
                        "placa" => $this->request->data["placa"]
            ));
        }
        return 0;
    }

    /**
     * Funcion que llama el logout despues de recibir los datos de la tableta
     * @return 1 ó 0
     */
    public function logout() {
        $this->redirect($this->Auth->logout());
    }

    /**
     * Funcion que obtiene los recorridos respectivos, con estado activo, y que sea del dia de hoy
     * @return JSON array
     */
    public function recorridos_get() {
        $recorridos = $this->Recorrido->find('all', array(
            'conditions' => array(
                'Recorrido.estado_recorrido' => 'activo'
            )
        ));

        $fecha = getdate();
        $diaNumerico = $fecha['wday'];
        switch ($diaNumerico) {
            case 1:
                $dia = "L";
                break;
            case 2:
                $dia = "M";
                break;
            case 3:
                $dia = "W";
                break;
            case 4:
                $dia = "J";
                break;
            case 5:
                $dia = "V";
                break;
            case 6:
                $dia = "S";
                break;
            case 0:
                $dia = "D";
                break;
        }

        foreach ($recorridos as $key => $recorrido) {
            $hora_actual = strtotime(date("H:i:s"));
            $hora_recorrido = strtotime($recorrido['Horario']['hora_salida']);
            $hora_min = $hora_actual - (60 * intval(Configure::read('Rastreo.start_time_range')));
            $hora_max = $hora_actual + (60 * intval(Configure::read('Rastreo.start_time_range')));


            if (strpos($recorrido['Horario']['dias_aplica'], $dia) === FALSE || $hora_recorrido < $hora_min || $hora_recorrido > $hora_max) {
                unset($recorridos[$key]);
            }
        }

        $recorridosNIndex = array_values($recorridos);
        echo json_encode($recorridosNIndex, JSON_UNESCAPED_UNICODE);
    }

    /**
     * Funcion para iniciar los recorridos realizados.
     * Primero busca todos los recorridos realizados con el id_recorrido respectivo y luego
     * filtra por la fecha que sea del dia de hoy y por el estado, que no este finalizado
     * luego si encuentra algun recorrido realizado, procese a cambiar los campos
     * sino, crea un nuevo recorrido realizado
     * @return id_recorrido_realizado
     */
    public function recorridos_realizados_iniciar() {

        if (isset($this->request->data['tag']) && $this->request->data['tag'] == 'INICIAR') {
            $tag = $this->request->data['tag']; //=TEST_TAG
            $androidPOST = array(
                'id_recorrido' => $this->request->data['id_recorrido'],
                'id_conductor' => $this->request->data['id_conductor'],
                'id_bus' => $this->request->data['id_bus'],
                'latitud' => $this->request->data['latitud'],
                'longitud' => $this->request->data['longitud'],
                'velocidad' => $this->request->data['velocidad'],
                'puestos_ocupados' => $this->request->data['puestos_ocupados']
            );

            $recorrido_obtenido = $this->Recorrido->find('first', array(
                'conditions' => array(
                    'Recorrido.id_recorrido' => $androidPOST['id_recorrido']
                )
            ));

            $rutaparada = $this->RutaParada->find('first', array(
                'conditions' => array(
                    'RutaParada.id_ruta' => $recorrido_obtenido['Recorrido']['id_ruta'],
                    'RutaParada.orden_ruta' => 1
                )
            ));

            $parada_origen = $this->Parada->find('first', array(
                'conditions' => array(
                    'Parada.id_parada' => $rutaparada['RutaParada']['id_parada']
                )
            ));

            $distance = $this->_getDistanceFromLatLonInKm($androidPOST['latitud'], $androidPOST['longitud'], $parada_origen['Parada']['latitud'], $parada_origen['Parada']['longitud']);


            $recorridoRealizadoObtenido = $this->RecorridoRealizado->find('all', array(
                'conditions' => array(
                    'RecorridoRealizado.id_recorrido' => $androidPOST['id_recorrido']
                //'RecorridoRealizado.estado_recorrido_realizado'=>'programado'
                )
            ));

            foreach ($recorridoRealizadoObtenido as $key => $recorridoR) {
                if (substr($recorridoR['RecorridoRealizado']['fecha_salida'], 0, 10) != date('Y-m-d') || $recorridoR['RecorridoRealizado']['estado_recorrido_realizado'] == 'finalizado') {
                    unset($recorridoRealizadoObtenido[$key]);
                }
            }
            $recorridoRealizadoNIndex = array_values($recorridoRealizadoObtenido);

            $returnArray = array(
                'error' => false,
                'id_recorrido_realizado' => 0,
                'alejado' => false,
                'errorDesc' => ""
            );

            if ($recorridoRealizadoNIndex != null) { //si encuentra el recorrido realizado
                if ($recorridoRealizadoNIndex[0]['RecorridoRealizado']['estado_recorrido_realizado'] == "programado" && floatval($distance) > floatval(Configure::read('Rastreo.stop_detection_maxdistance')) * floatval(Configure::read('Rastreo.travel_start_factor'))) {
                    $returnArray['alejado'] = true;
                    $returnArray['errorDesc'] = "Esta muy alejado de la parada inicial";
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                }
                $recorridoRealizadoNIndex[0]['RecorridoRealizado']['latitud'] = $androidPOST['latitud'];
                $recorridoRealizadoNIndex[0]['RecorridoRealizado']['longitud'] = $androidPOST['longitud'];
                $recorridoRealizadoNIndex[0]['RecorridoRealizado']['id_conductor'] = $androidPOST['id_conductor'];
                $recorridoRealizadoNIndex[0]['RecorridoRealizado']['id_bus'] = $androidPOST['id_bus'];
                $recorridoRealizadoNIndex[0]['RecorridoRealizado']['velocidad_promedio'] = $androidPOST['velocidad'];
                //$recorridoRealizadoNIndex[0]['RecorridoRealizado']['puestos_ocupados']=0;
                $recorridoRealizadoNIndex[0]['RecorridoRealizado']['estado_recorrido_realizado'] = "movimiento";

                try {
                    if ($this->RecorridoRealizado->save($recorridoRealizadoNIndex[0], false, true)) {
                        $returnArray['id_recorrido_realizado'] = $recorridoRealizadoNIndex[0]['RecorridoRealizado']['id_recorrido_realizado'];

                        $this->RecorridoRealizadoHistorico->create();
                        $this->RecorridoRealizadoHistorico->set(array(
                            'id_recorrido_realizado' => $returnArray['id_recorrido_realizado'],
                            'fecha_hora_guardado_servidor' => date('Y-m-d H:i:s'),
                            'fecha_hora_solicitud_gps' => $this->request->data['fecha_solicitar_posicion'],
                            'fecha_hora_envio_servidor' => $this->request->data['fecha_posicion_obtenida'],
                            'latitud' => $androidPOST['latitud'],
                            'longitud' => $androidPOST['longitud'],
                            'velocidad' => $androidPOST['velocidad']
                        ));
                        $this->RecorridoRealizadoHistorico->save($this->RecorridoRealizadoHistorico->data);

                        return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                    } else
                        $returnArray['error'] = true;
                    $returnArray['errorDesc'] = "Hubo un error al crear el RecorridoRealizado";
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                } catch (Exception $e) {
                    $returnArray['error'] = true;
                    $returnArray['errorDesc'] = "Hubo un error al crear el RecorridoRealizado";
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                }
            } else {
                if (floatval($distance) > floatval(Configure::read('Rastreo.stop_detection_maxdistance')) * floatval(Configure::read('Rastreo.travel_start_factor'))) {
                    $returnArray['alejado'] = true;
                    $returnArray['errorDesc'] = "Esta muy alejado de la parada inicial";
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                }
                $this->RecorridoRealizado->create();
                $this->RecorridoRealizado->set(array(
                    'estado_recorrido_realizado' => 'movimiento',
                    'fecha_salida' => date('Y-m-d H:i:s'),
                    "id_recorrido" => $androidPOST['id_recorrido'],
                    "id_bus" => $androidPOST['id_bus'],
                    "id_conductor" => $androidPOST['id_conductor'],
                    'puestos_reservados' => 0,
                    'puestos_ocupados' => 0,
                    'latitud' => $androidPOST['latitud'],
                    'longitud' => $androidPOST['longitud'],
                    'velocidad_promedio' => $androidPOST['velocidad']
                ));
                try {
                    if ($this->RecorridoRealizado->save($this->RecorridoRealizado->data, false, true)) {
                        $tempRecorridoRealizado = $this->RecorridoRealizado->find('first', array(
                            'conditions' => array(
                                'RecorridoRealizado.id_recorrido' => $androidPOST['id_recorrido'],
                                'RecorridoRealizado.id_bus' => $androidPOST['id_bus'],
                                'RecorridoRealizado.id_conductor' => $androidPOST['id_conductor'],
                                'RecorridoRealizado.latitud' => $androidPOST['latitud'],
                                'RecorridoRealizado.longitud' => $androidPOST['longitud']
                            )
                        ));
                        $returnArray['id_recorrido_realizado'] = $tempRecorridoRealizado['RecorridoRealizado']['id_recorrido_realizado'];

                        $this->RecorridoRealizadoHistorico->create();
                        $this->RecorridoRealizadoHistorico->set(array(
                            'id_recorrido_realizado' => $returnArray['id_recorrido_realizado'],
                            'fecha_hora_guardado_servidor' => date('Y-m-d H:i:s'),
                            'fecha_hora_solicitud_gps' => $this->request->data['fecha_solicitar_posicion'],
                            'fecha_hora_envio_servidor' => $this->request->data['fecha_posicion_obtenida'],
                            'latitud' => $androidPOST['latitud'],
                            'longitud' => $androidPOST['longitud'],
                            'velocidad' => $androidPOST['velocidad']
                        ));
                        $this->RecorridoRealizadoHistorico->save($this->RecorridoRealizadoHistorico->data);

                        return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                    } else {
                        $returnArray['error'] = true;
                        $returnArray['errorDesc'] = "Hubo un error al crear el RecorridoRealizado";
                        return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                    }
                } catch (Exception $e) {
                    $returnArray['error'] = true;
                    $returnArray['errorDesc'] = "Hubo un error al crear el RecorridoRealizado";
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                }
            }
        }
    }

    /**
     * Funcion para actualizar el recorrido realizado y asi pueda hacerse correctamente el seguimiento del bus
     * @return id_recorrido_realizado
     */
    public function actualizar_posicion() {
        if (isset($this->request->data['tag']) && $this->request->data['tag'] == 'ACTUALIZAR') {

            $recorridoRealizado = $this->RecorridoRealizado->find('first', array(
                'conditions' => array(
                    'RecorridoRealizado.id_recorrido_realizado' => $this->request->data['id_recorrido_realizado']
                )
            ));

            $recorridoRealizado['RecorridoRealizado']['velocidad_promedio'] = $this->request->data['velocidad'];
            $recorridoRealizado['RecorridoRealizado']['fecha_actualizacion_recorrido'] = date('Y/m/j H:i:s');

            if ($recorridoRealizado['RecorridoRealizado']['estado_recorrido_realizado'] != 'evento' && $recorridoRealizado['RecorridoRealizado']['estado_recorrido_realizado'] != 'finalizado') {
                $distance = $this->_getDistanceFromLatLonInKm($recorridoRealizado['RecorridoRealizado']['latitud'], $recorridoRealizado['RecorridoRealizado']['longitud'], $this->request->data["latitud"], $this->request->data["longitud"]);

                if ($distance <= floatval(Configure::read('Rastreo.max_stopped_distance'))) {
                    $recorridoRealizado['RecorridoRealizado']['contador_inactividad'] ++;
                } else {
                    $recorridoRealizado['RecorridoRealizado']['contador_inactividad'] = 0;
                }

                if ($recorridoRealizado['RecorridoRealizado']['contador_inactividad'] > Configure::read('Rastreo.max_stopped_times')) {
                    $recorridoRealizado['RecorridoRealizado']['estado_recorrido_realizado'] = 'detenido';
                } else {
                    $recorridoRealizado['RecorridoRealizado']['estado_recorrido_realizado'] = 'movimiento';
                }
            }
            $recorridoRealizado['RecorridoRealizado']['latitud'] = $this->request->data['latitud'];
            $recorridoRealizado['RecorridoRealizado']['longitud'] = $this->request->data['longitud'];

            $returnArray = array(
                'error' => false,
                'errorDesc' => ""
            );
            try {
                if ($this->RecorridoRealizado->save($recorridoRealizado, false, true)) {
                    $this->RecorridoRealizadoHistorico->create();
                    $this->RecorridoRealizadoHistorico->set(array(
                        'id_recorrido_realizado' => $this->request->data['id_recorrido_realizado'],
                        'fecha_hora_guardado_servidor' => date('Y-m-d H:i:s'),
                        'fecha_hora_solicitud_gps' => $this->request->data['fecha_solicitar_posicion'],
                        'fecha_hora_envio_servidor' => $this->request->data['fecha_posicion_obtenida'],
                        'latitud' => $recorridoRealizado['RecorridoRealizado']['latitud'],
                        'longitud' => $recorridoRealizado['RecorridoRealizado']['longitud'],
                        'velocidad' => $recorridoRealizado['RecorridoRealizado']['velocidad_promedio']
                    ));
                    $errorHistorial = null;
                    if ($this->RecorridoRealizadoHistorico->save($this->RecorridoRealizadoHistorico->data)) {
                        $errorHistorial = null;
                    } else {
                        $errorHistorial = "Error al guardar el recorrrido realizdo historico";
                    }
                    $return = $this->_actualizar_rrparadas($recorridoRealizado, $errorHistorial);
                    return $return;
                } else {
                    $returnArray['error'] = true;
                    $returnArray['errorDesc'] = "Error al guardar el RecorridoRealizado";
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                }
            } catch (Exception $e) {
                $returnArray['error'] = true;
                $returnArray['errorDesc'] = "Error en el metodo actualizar_posicion (Exception)";
                return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
            }
        }
    }

    public function _actualizar_rrparadas($recorridoRealizado = null, $errorHistorial = "") {
        if (isset($recorridoRealizado['RecorridoRealizado']['id_recorrido_realizado'])) {
            $recorrido = $this->Recorrido->find('all', array(
                'conditions' => array(
                    'Recorrido.id_recorrido' => $recorridoRealizado['RecorridoRealizado']['id_recorrido']
                )
            ));

            $rutasparadas = $this->RutaParada->find('all', array(
                'conditions' => array(
                    'RutaParada.id_ruta=' . $recorrido[0]['Recorrido']["id_ruta"]
                ),
                'order' => array(
                    'RutaParada.orden_ruta ASC'
                )
            ));

            $infoJSON = array(
                'error' => false,
                'parada_cercana' => null,
                'llego_parada' => "no",
                'finalizar_recorrido' => false,
                'proxima_parada' => null,
                'proxima_parada_reservas' => null,
                'proxima_parada1' => null,
                'proxima_parada2' => null,
                'puestos_disponibles' => null,
                'puestos_ocupados' => null,
                'errorDesc2' => "",
                'errorHistorial' => $errorHistorial
            );

            if (!isset($recorridoRealizado['RecorridoRealizado']['id_proxima_parada']) || empty($recorridoRealizado['RecorridoRealizado']['id_proxima_parada'])) {
                $recorridoRealizado['RecorridoRealizado']['id_proxima_parada'] = $rutasparadas[1]["RutaParada"]["id_parada"];
                if ($this->RecorridoRealizado->save($recorridoRealizado, false, true)) {
                    
                } else {
                    $infoJSON['error'] = true;
                    $infoJSON['errorDesc2'] = "Error al actualizar id de la proxima parada en el metodo _actualizar_rrparadas";
                }
            }

            $parada_cercana = null;
            foreach ($rutasparadas as $key => $value) {
                $element = array(
                    'Parada' => $value["Parada"],
                    'orden_ruta' => $value["RutaParada"]["orden_ruta"],
                    'tipo_parada' => $value["RutaParada"]["tipo_parada"],
                    'distance' => $this->_getDistanceFromLatLonInKm($recorridoRealizado['RecorridoRealizado']['latitud'], $recorridoRealizado['RecorridoRealizado']['longitud'], $value["Parada"]["latitud"], $value["Parada"]["longitud"])
                );
                if (empty($parada_cercana) && $key >= 0) {
                    $parada_cercana = $element;
                } else if (!empty($parada_cercana) && $element['distance'] < $parada_cercana['distance'] && $element['orden_ruta'] > $parada_cercana['orden_ruta']) {
                    $parada_cercana = $element;
                }
            }

            $pp = $this->Parada->find('first', array('conditions' => array(
                    'Parada.id_parada' => $recorridoRealizado['RecorridoRealizado']['id_proxima_parada']
            )));
            $reservas_parada = $this->Reserva->find('all', array('conditions' => array(
                    'Reserva.id_parada' => $recorridoRealizado['RecorridoRealizado']['id_proxima_parada'],
                    'Reserva.id_recorrido_realizado' => $recorridoRealizado['RecorridoRealizado']['id_recorrido_realizado']
            )));

            $infoJSON['proxima_parada'] = $pp['Parada']['nombre_parada'];
            $infoJSON['proxima_parada_reservas'] = sizeof($reservas_parada);
            $indice = 0;
            while ($rutasparadas[$indice]['RutaParada']['id_parada'] != $pp['Parada']['id_parada']) {
                $indice++;
            }

            if (array_key_exists($indice + 1, $rutasparadas)) {
                $infoJSON['proxima_parada1'] = $rutasparadas[$indice + 1]['Parada']['nombre_parada'];
            }

            if (array_key_exists($indice + 2, $rutasparadas)) {
                $infoJSON['proxima_parada2'] = $rutasparadas[$indice + 2]['Parada']['nombre_parada'];
            }

            if (!empty($parada_cercana) && floatval($parada_cercana['distance']) <= floatval(Configure::read('Rastreo.stop_detection_maxdistance')) * floatval(Configure::read('Rastreo.proximity_factor'))) {
                //echo $parada_cercana['Parada']['id_parada'];
                $infoJSON['parada_cercana'] = $parada_cercana['Parada']['id_parada'];
            }

            $dispo = $recorridoRealizado['Bus']['capacidad'] - $recorridoRealizado['RecorridoRealizado']['puestos_ocupados'] - $recorridoRealizado['RecorridoRealizado']['puestos_reservados'];
            $infoJSON['puestos_disponibles'] = $dispo;
            $infoJSON['puestos_ocupados'] = $recorridoRealizado['RecorridoRealizado']['puestos_ocupados'];

            if (!empty($parada_cercana) && floatval($parada_cercana['distance']) <= floatval(Configure::read('Rastreo.stop_detection_maxdistance')) && floatval($recorridoRealizado['RecorridoRealizado']['velocidad_promedio']) <= floatval(Configure::read('Rastreo.stop_detection_maxspeed'))) {
                $rrpar = $this->RecorridoRealizadoParada->find('first', array(
                    'conditions' => array(
                        'RecorridoRealizadoParada.id_recorrido_realizado' => $recorridoRealizado['RecorridoRealizado']['id_recorrido_realizado'],
                        'RecorridoRealizadoParada.id_parada' => $parada_cercana['Parada']['id_parada']
                    )
                ));
                if (!$rrpar) {
                    $this->RecorridoRealizadoParada->create();
                    $this->RecorridoRealizadoParada->set(array(
                        'id_recorrido_realizado' => $recorridoRealizado['RecorridoRealizado']['id_recorrido_realizado'],
                        'hora_llegada_parada' => date('h:i'),
                        'id_parada' => $parada_cercana['Parada']['id_parada']
                    ));
                    if ($this->RecorridoRealizadoParada->save($this->RecorridoRealizadoParada->data, false)) {
                        $infoJSON['llego_parada'] = "si";
                    } else {
                        $infoJSON['error'] = true;
                        $infoJSON['errorDesc2'] = "Error al crear el RecorridoRealizadoParada en el metodo _actualizar_rrparadas";
                    }

                    foreach ($rutasparadas as $key => $value) {
                        if ($value["RutaParada"]["orden_ruta"] == $parada_cercana["orden_ruta"] + 1) {
                            $recorridoRealizado['RecorridoRealizado']['id_proxima_parada'] = $value["RutaParada"]["id_parada"];
                            if ($this->RecorridoRealizado->save($recorridoRealizado, false, true)) {
                                
                            } else {
                                $infoJSON['error'] = true;
                                $infoJSON['errorDesc2'] = "Error al actualizar id de la proxima parada en el metodo _actualizar_rrparadas";
                            }
                        }
                    }
                    if ($parada_cercana["tipo_parada"] == 'destino') {
                        $recorridoRealizado['RecorridoRealizado']['fecha_llegada'] = date('Y-m-d H:i:s');
                        $recorridoRealizado['RecorridoRealizado']['estado_recorrido_realizado'] = 'finalizado';
                        if ($this->RecorridoRealizado->save($recorridoRealizado, false)) {
                            $infoJSON['finalizar_recorrido'] = true;
                            $this->Reserva->verificarReservas($this->request->data['id_recorrido_realizado']);
                        } else {
                            $infoJSON['error'] = true;
                            $infoJSON['errorDesc2'] = "Error al finalizar el RecorridoRealizado _actualizar_rrparadas";
                        }
                    }
                }
            }
            return json_encode($infoJSON, JSON_UNESCAPED_UNICODE);
        }
    }

    public function _getDistanceFromLatLonInKm($lat1, $lon1, $lat2, $lon2) {
        $R = 6372.797; // Radius of the earth in km
        $dLat = deg2rad($lat2 - $lat1); // deg2rad below
        $dLon = deg2rad($lon2 - $lon1);
        $a = sin($dLat / 2) * sin($dLat / 2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon / 2) * sin($dLon / 2);
        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
        $d = $R * $c; // Distance in km
        return $d;
    }

    /**
     * Funcion para obtener los eventos disponibles
     * @return JSON array
     */
    public function eventos_get() {
        $eventos = $this->Evento->find('all');
        return json_encode($eventos, JSON_UNESCAPED_UNICODE);
    }

    /**
     * Funcion para obtener los buses disponibles
     * @return JSON array
     */
    public function buses_get() {
        $recorridosR = $this->RecorridoRealizado->find('all', array(
            'conditions' => array(
                'RecorridoRealizado.estado_recorrido_realizado' => "movimiento"
            )
        ));
        $buses = $this->Bus->find('all', array(
            'conditions' => array(
                'Bus.estado_bus' => "activo"
            )
        ));
        foreach ($buses as $key1 => $bus) {
            foreach ($recorridosR as $key2 => $recorrido) {
                if ($bus['Bus']['id_bus'] == $recorrido['RecorridoRealizado']['id_bus'])
                    unset($buses[$key1]);
            }
        }
        $busesNIndex = array_values($buses);
        return json_encode($busesNIndex, JSON_UNESCAPED_UNICODE);
    }

    /**
     * Funcion para agregar un evento al recorrido realizado
     * @return 1 ó 0
     */
    public function agregar_evento() {
        if (isset($this->request->data['tag']) && $this->request->data['tag'] == 'EVENTO') {

            $this->RecorridoRealizadoEvento->create();
            $this->RecorridoRealizadoEvento->set(array(
                'id_recorrido_realizado' => $this->request->data['id_recorrido_realizado'],
                'id_evento' => $this->request->data['id_evento'],
                'latitud' => $this->request->data['latitud'],
                'longitud' => $this->request->data['longitud']
            ));
            $recorridoRealizado = $this->RecorridoRealizado->find('first', array(
                'conditions' => array(
                    'RecorridoRealizado.id_recorrido_realizado' => $this->request->data['id_recorrido_realizado']
                )
            ));
            $recorridoRealizado['RecorridoRealizado']['estado_recorrido_realizado'] = "evento";
            $returnArray = array(
                'error' => false,
                'errorDesc' => ""
            );
            try {
                if ($this->RecorridoRealizadoEvento->save($this->RecorridoRealizadoEvento->data, false, true) && $this->RecorridoRealizado->save($recorridoRealizado, false, true)) {
                    $this->notificar_evento($this->request->data['id_recorrido_realizado'], $this->request->data['id_evento']);
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                } else {
                    $returnArray['error'] = true;
                    $returnArray['errorDesc'] = "Error al guardar el evento en el metodo agregar_evento";
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                }
            } catch (Exception $e) {
                $returnArray['error'] = true;
                $returnArray['errorDesc'] = "Error al guardar el evento en el metodo agregar_evento";
                return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
            }
        }
    }

    /**
     * Funcion para finalizar un recorrido realizado, simplemente con el id_recorrido_realizado,
     * le cambia el estado y luego verifica cada una de las reservas, que si se hayan utilizado
     * @return 1 ó 0
     */
    public function finalizar_recorrido() {
        if (isset($this->request->data['tag']) && $this->request->data['tag'] == 'FINALIZAR') {
            $recorridoRealizado = $this->RecorridoRealizado->find('first', array(
                'conditions' => array(
                    'RecorridoRealizado.id_recorrido_realizado' => $this->request->data['id_recorrido_realizado']
                )
            ));
            $recorridoRealizado['RecorridoRealizado']['estado_recorrido_realizado'] = "finalizado";

            if (!isset($recorridoRealizado['RecorridoRealizado']['fecha_llegada'])) {
                $recorridoRealizado['RecorridoRealizado']['fecha_llegada'] = date('Y/m/j H:i:s');
            }
            $returnArray = array(
                'error' => false,
                'errorDesc' => ""
            );
            try {
                if ($this->RecorridoRealizado->save($recorridoRealizado, false, true)) {
                    $this->Reserva->verificarReservas($this->request->data['id_recorrido_realizado']);
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                } else {
                    $returnArray['error'] = true;
                    $returnArray['errorDesc'] = "Error al finalizar el RecorridoRealizado en el metodo finalizar_recorrido";
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                }
            } catch (Exception $e) {
                $returnArray['error'] = true;
                $returnArray['errorDesc'] = "Error al finalizar el RecorridoRealizado en el metodo finalizar_recorrido";
                return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
            }
        }
    }

    /**
     * Funcion para verificar la cedula de cada usuario de mibus, obtiene la cedula y lo guarda,
     * luego agrega el lugar de subida al bus en la ultima parada del bus.
     * si el bus ya ha parado pone la ultima parada pero sino  ha hecho paradas, crea una parada con la primera parada del bus
     * @return 1 ó 0
     */
    public function verificar_cedula() {
        if (isset($this->request->data['tag']) && $this->request->data['tag'] == 'CEDULA') {
            $WSClienteConsultaCedula = new SoapClient(null, array(
                'location' => 'https://eiadigital.eia.edu.co/WSConsultaCedula/',
                'uri' => 'urn:ConsultaCedula'
            ));
            $Registro = $WSClienteConsultaCedula->ConsultaCedula($this->request->data['cedula']);

            if ($Registro) {
                $user = $this->RecorridoRealizadoUsuarioParada->find('first', array(
                    'conditions' => array(
                        'RecorridoRealizadoUsuarioParada.id_recorrido_realizado' => $this->request->data['id_recorrido_realizado'],
                        'RecorridoRealizadoUsuarioParada.id_usuario' => $this->request->data['cedula']
                    )
                ));

                if (!$user) {
                    $recorridoRealizadoPuestos = $this->RecorridoRealizado->find('first', array(
                        'conditions' => array(
                            'RecorridoRealizado.id_recorrido_realizado' => $this->request->data['id_recorrido_realizado']
                        )
                    ));
                    $bus = $this->Bus->find('first', array(
                        'conditions' => array(
                            'Bus.id_bus' => $this->request->data['id_bus']
                        )
                    ));
                    $totOcupados = $recorridoRealizadoPuestos['RecorridoRealizado']['puestos_ocupados'];
                    $totReservados = $recorridoRealizadoPuestos['RecorridoRealizado']['puestos_reservados'];

                    if ($totOcupados + $totReservados < $bus['Bus']['capacidad']) {

                        $recorridoRealizadoParada = $this->RecorridoRealizadoParada->find('first', array(
                            'conditions' => array(
                                "RecorridoRealizadoParada.id_recorrido_realizado" => $this->request->data['id_recorrido_realizado']
                            ),
                            'order' => 'RecorridoRealizadoParada.hora_llegada_parada DESC'
                        ));

                        if ($recorridoRealizadoParada) {
                            $this->RecorridoRealizadoUsuarioParada->create();
                            $this->RecorridoRealizadoUsuarioParada->set(array(
                                'id_recorridos_realizados_paradas' => $recorridoRealizadoParada['RecorridoRealizadoParada']['id_recorridos_realizados_paradas'],
                                'id_usuario' => $this->request->data['cedula'],
                                "id_recorrido_realizado" => $this->request->data['id_recorrido_realizado'],
                                'tipo_movimiento' => 1
                            ));
                            if ($this->RecorridoRealizadoUsuarioParada->save($this->RecorridoRealizadoUsuarioParada->data, false) && $this->aumentar_puestos_ocupados($this->request->data['cedula'], $this->request->data['id_recorrido_realizado']))
                                echo 1;
                            else
                                echo 3;
                        } else {
                            $rrealizado = $this->RecorridoRealizado->find('first', array(
                                'conditions' => array(
                                    'RecorridoRealizado.id_recorrido_realizado' => $this->request->data['id_recorrido_realizado']
                                ),
                                'recursive' => 0
                            ));

                            $rparadas = $this->RutaParada->find('first', array(
                                'conditions' => array(
                                    'RutaParada.id_ruta' => $rrealizado['Recorrido']['id_ruta'],
                                    'RutaParada.orden_ruta' => 1
                                )
                            ));

                            $this->RecorridoRealizadoParada->create();
                            $this->RecorridoRealizadoParada->set(array(
                                'id_recorrido_realizado' => $this->request->data['id_recorrido_realizado'],
                                'id_parada' => $rparadas['RutaParada']['id_parada'],
                                'hora_llegada_parada' => date("Y/m/j H:i:s")
                            ));

                            if ($this->RecorridoRealizadoParada->save($this->RecorridoRealizadoParada->data, false)) {
                                $recorridoRealizadoParada = $this->RecorridoRealizadoParada->find('first', array(
                                    'conditions' => array(
                                        'RecorridoRealizadoParada.id_recorrido_realizado' => $this->request->data['id_recorrido_realizado'],
                                        'RecorridoRealizadoParada.id_parada' => $rparadas['RutaParada']['id_parada']
                                    )
                                ));
                                $this->RecorridoRealizadoUsuarioParada->create();
                                $this->RecorridoRealizadoUsuarioParada->set(array(
                                    'id_recorridos_realizados_paradas' => $recorridoRealizadoParada['RecorridoRealizadoParada']['id_recorridos_realizados_paradas'],
                                    'id_usuario' => $this->request->data['cedula'],
                                    'id_recorrido_realizado' => $this->request->data['id_recorrido_realizado'],
                                    'tipo_movimiento' => 1
                                ));
                                if ($this->RecorridoRealizadoUsuarioParada->save($this->RecorridoRealizadoUsuarioParada->data, false) && $this->aumentar_puestos_ocupados($this->request->data['cedula'], $this->request->data['id_recorrido_realizado']))
                                    echo 1;
                                else
                                    echo 3;
                            } else { //
                                echo 2;
                            }
                        } //aqui acaba todo lo relacionado con verificar la cedula
                    } else {
                        echo -1;
                    } //fin si hay puestos libres
                } else {
                    echo 4;
                } //fin de si la persona ya se subio al bus
            } else {
                echo 0;
            }
        }
    }

    public function aumentar_puestos_ocupados($id_usuario, $id_recorrido_realizado) {
        $recorridoRealizado = $this->RecorridoRealizado->find('first', array(
            'conditions' => array(
                'RecorridoRealizado.id_recorrido_realizado' => $id_recorrido_realizado
            )
        ));
        $reserva = $this->Reserva->find('first', array(
            'conditions' => array(
                'Reserva.id_recorrido_realizado' => $id_recorrido_realizado,
                'Reserva.id_usuario' => $id_usuario
            )
        ));
        if ($reserva) {
            return true;
        } else {
            $recorridoRealizado['RecorridoRealizado']['puestos_ocupados'] += 1;
            if ($this->RecorridoRealizado->save($recorridoRealizado, false, true)) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * Funcion para notificar a todas las reservas del recorrido que el bus ha tenido un evento
     * @return void
     */
    public function notificar_evento($id_recorrido_realizado, $id_evento) {
        $evento = $this->Evento->find('first', array(
            'conditions' => array(
                'Evento.id_evento' => $id_evento
            )
        ));

        $buses = $this->RecorridoRealizado->Bus->find('all', array(
            'conditions' => array(
                'Bus.estado_bus' => 'activo'
            )
        ));

        $conductores = $this->RecorridoRealizado->Conductor->find('all', array(
            'conditions' => array(
                'Conductor.estado_conductor' => 'activo'
            )
        ));

        $recorridos = $this->RecorridoRealizado->Recorrido->find('all', array(
            'conditions' => array(
                'Recorrido.estado_recorrido' => 'activo'
            )
        ));

        $reservas = $this->Reserva->find('all', array(
            'conditions' => array(
                'Reserva.id_recorrido_realizado' => $id_recorrido_realizado
            )
        ));

        $rr = $this->RecorridoRealizado->find('first', array(
            'conditions' => array(
                'RecorridoRealizado.id_recorrido_realizado' => $id_recorrido_realizado
            )
        ));

        if (count($reservas) > 0) {
            foreach ($buses as $bus) {
                if ($bus['Bus']['id_bus'] == $rr['Bus']['id_bus']) {
                    $busElegido = $bus;
                }
            }
            foreach ($conductores as $conductor) {
                if ($conductor['Conductor']['id_conductor'] == $rr['Conductor']['id_conductor']) {
                    $conductorElegido = $conductor;
                }
            }
            $correos = array();
            foreach ($reservas as $res) {
                $usuario = $res['Reserva']['id_usuario'];
                $usuarioObjeto = $this->Usuario->find('all', array(
                    'conditions' => array(
                        'Usuario.identificacion_usuario' => $usuario
                    )
                ));
                $correo = $usuarioObjeto[0]['Usuario']['correo'];
                if (!empty($correo)) {
                    $correos[] = $correo;
                }
            }

            if (count($correos) > 0) {
                $Email = new CakeEmail('default');
                $Email->template("rre_notification", "email_miBus")->emailFormat('both');
                $Email->bcc($correos);
                $Email->subject("Su Recorrido ha sufrido una eventualidad");
                $Email->viewVars(array(
                    'placa' => $busElegido['Bus']['placa'],
                    'capacidad' => $busElegido['Bus']['capacidad'],
                    'empresa' => $busElegido['Bus']['empresa'],
                    'driverName' => $conductorElegido['Conductor']['nombre_conductor'],
                    'reservedSpots' => $rr['RecorridoRealizado']['puestos_reservados'],
                    'departure' => $recorrido_realizado['RecorridoRealizado']['fecha_salida'],
                    'state' => $rr['RecorridoRealizado']['estado_recorrido_realizado'],
                    'evento' => $evento['Evento']['nombre_evento']
                ));
                $Email->send("");
            }
        }
    }

    /**
     * Funcion para cambiar la próxima parada de un recorrido realizado a la siguiente
     * @return void
     */
    public function saltar_parada() {
        if (isset($this->request->data['id_recorrido_realizado'])) {
            $recorridoRealizado = $this->RecorridoRealizado->find('first', array(
                'conditions' => array(
                    'RecorridoRealizado.id_recorrido_realizado' => $this->request->data['id_recorrido_realizado']
                )
            ));

            if (isset($recorridoRealizado['RecorridoRealizado']['id_recorrido_realizado'])) {
                $recorrido = $this->Recorrido->find('all', array(
                    'conditions' => array(
                        'Recorrido.id_recorrido' => $recorridoRealizado['RecorridoRealizado']['id_recorrido']
                    )
                ));

                $rutasparadas = $this->RutaParada->find('all', array(
                    'conditions' => array(
                        'RutaParada.id_ruta' => $recorrido[0]['Recorrido']["id_ruta"]
                    ),
                    'order' => array(
                        'RutaParada.orden_ruta ASC'
                    )
                ));

                $parada_actual_encontrada = false;
                $returnArray = array('error' => false, 'tipo' => 0, 'errorDesc' => "");

                foreach ($rutasparadas as $key => $value) {
                    if ($parada_actual_encontrada) {
                        if (!empty($value["Parada"]["id_parada"])) {
                            $recorridoRealizado['RecorridoRealizado']['id_proxima_parada'] = $value["Parada"]["id_parada"];
                            $this->RecorridoRealizado->save($recorridoRealizado, false, true);
                            return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                        }
                    }
                    if ($value["Parada"]["id_parada"] == $recorridoRealizado['RecorridoRealizado']['id_proxima_parada']) {
                        $parada_actual_encontrada = true;
                    }
                }
                $parada_actual_encontrada = false;
                if (!$parada_actual_encontrada) {
                    $returnArray['error'] = true;
                    $returnArray['errorDesc'] = "No se pudo saltar parada, porque la proxima parada es la parada final";
                    $returnArray['tipo'] = 1;
                    return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
                }
                $returnArray['error'] = true;
                $returnArray['errorDesc'] = "No se pudo saltar parada, error al encontrar la proxima parada en el metodo saltar_parada";
                $returnArray['tipo'] = 2;
                return json_encode($returnArray, JSON_UNESCAPED_UNICODE);
            }
        }
    }

    /**
     * Funcion para aumentar los puestos ocupados para cuando algun usuario no tiene cédula
     * @return void
     */
    public function aumentar_puestos_ocupados_sin() {
        if (isset($this->request->data['id_recorrido_realizado']) && isset($this->request->data['id_bus'])) {
            $recorridoRealizado = $this->RecorridoRealizado->find('first', array(
                'conditions' => array(
                    'RecorridoRealizado.id_recorrido_realizado' => $this->request->data['id_recorrido_realizado']
                )
            ));
            $bus = $this->Bus->find('first', array(
                'conditions' => array(
                    'Bus.id_bus' => $this->request->data['id_bus']
                )
            ));
            $totOcupados = $recorridoRealizado['RecorridoRealizado']['puestos_ocupados'];
            $totReservados = $recorridoRealizado['RecorridoRealizado']['puestos_reservados'];

            if ($totOcupados + $totReservados < $bus['Bus']['capacidad']) {
                $recorridoRealizado['RecorridoRealizado']['puestos_ocupados'] += 1;
                if ($this->RecorridoRealizado->save($recorridoRealizado, false, true)) {
                    return 1;
                } else {
                    return 0;
                }
            } else {
                return 2;
            }
        }
        return 0;
    }

}

//fin